package com.lhj.xxsc.auth.controller;

import com.alibaba.fastjson.TypeReference;
import com.xxsc.common.constant.AuthServerConstant;
import com.xxsc.common.exception.BizCodeEnume;
import com.xxsc.common.utils.R;
import com.xxsc.common.vo.MemberRespVo;
import com.lhj.xxsc.auth.feign.MemberFeignService;
import com.lhj.xxsc.auth.feign.ThirdPartFeignService;
import com.lhj.xxsc.auth.vo.UserLoginVo;
import com.lhj.xxsc.auth.vo.UserRegistVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 罗惠江
 * @version 1.0
 * @email 1511619294@qq.com
 * @date 2020/12/24 14:21
 */
@Controller
public class LoginController {
	//	@GetMapping("/login.html")
//	public String loginPage(){
//		return "login";
//	}
//
//	@GetMapping("/reg.html")
//	public String regPage(){
//		return "reg";
//	}
	@Autowired
	ThirdPartFeignService thirdPartFeignService;

	@Autowired
	StringRedisTemplate redisTemplate;

	@Autowired
	MemberFeignService memberFeignService;

	@ResponseBody
	@GetMapping("/sms/sendcode")
	public R sendCode(@RequestParam("phone") String phone) {

		// TODO 接口防刷

		String oldCode = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
		if (!StringUtils.isEmpty(oldCode)) {
			long oldTime = Long.parseLong(oldCode.split("_")[1]);
			if (Instant.now().toEpochMilli() - oldTime < 60000) {
				return R.error(BizCodeEnume.SMS_CODE_PRODUCT_UP_EXCEPTION.getCode(), BizCodeEnume.SMS_CODE_PRODUCT_UP_EXCEPTION.getMsg());
			}
		}
		String sendCode = UUID.randomUUID().toString().substring(0, 5);
		String code = sendCode + "_" + Instant.now().toEpochMilli();
		redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone, code, 10, TimeUnit.MINUTES);
		thirdPartFeignService.sendCode(phone, sendCode);
		return R.ok();
	}


	/**
	 * @param vo
	 * @param result
	 * @param redirectAttributes 、、模拟重定向数据
	 * @return
	 */
	@PostMapping("/regist")
	public String regist(@Valid UserRegistVo vo, BindingResult result, RedirectAttributes redirectAttributes) {
		if (result.hasErrors()) {
			Map<String, String> errorMap = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
			// redirectAttributes.addAttribute("errors", errorMap);
			redirectAttributes.addFlashAttribute("errors", errorMap);
			// 校验出错，转发到注册页
			// post 不支持 forward 转发
			// TODO 存在SESSION 分布式问题
			return "redirect:http://auth.xxsc.com/reg.html";
		}
		// 真正注册，调用远程服务进行注册
		// 校验验证码
		String code = vo.getCode();
		String oldCodeTime = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
		if (!StringUtils.isEmpty(oldCodeTime)) {
			String[] oldCodeStr = oldCodeTime.split("_");
			long oldTime = Long.parseLong(oldCodeStr[1]);
			if (Instant.now().toEpochMilli() - oldTime < 300000) {
				if (code.equalsIgnoreCase(oldCodeStr[0])) {
					// 删除验证码
					redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vo.getPhone());
					// 验证码通过，远程调用会员注册功能
					R r = memberFeignService.regist(vo);
					if (r.getCode() == 0) {
						// 成功
						return "redirect:http://auth.xxsc.com/login.html";
					} else {
						Map<String, String> errorMap = new HashMap<>();
						errorMap.put("msg", r.getData("msg", new TypeReference<String>() {
						}));
						redirectAttributes.addFlashAttribute("errors", errorMap);
						return "redirect:http://auth.xxsc.com/reg.html";
					}
				} else {
					Map<String, String> errorMap = new HashMap<>();
					errorMap.put("code", "验证码错误");
					redirectAttributes.addFlashAttribute("errors", errorMap);
					return "redirect:http://auth.xxsc.com/reg.html";
				}
			} else {
				Map<String, String> errorMap = new HashMap<>();
				errorMap.put("code", "验证码过期");
				redirectAttributes.addFlashAttribute("errors", errorMap);
				return "redirect:http://auth.xxsc.com/reg.html";
			}
		} else {
			Map<String, String> errorMap = new HashMap<>();
			errorMap.put("code", "验证码错误");
			redirectAttributes.addFlashAttribute("errors", errorMap);
			return "redirect:http://auth.xxsc.com/reg.html";
		}
	}

	@RequestMapping("/login.html")
	public String loginPage(HttpSession session) {
		if (session.getAttribute(AuthServerConstant.LOGIN_USER) != null) {
			return "redirect:http://xxsc.com/";
		}else {
			return "login";
		}
	}

	@PostMapping("/login")
	public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session) {

		// 远程进行登录
		R r = memberFeignService.login(vo);
		if (r.getCode() == 0) {
			MemberRespVo data = r.getData("memberEntity", new TypeReference<MemberRespVo>() {
			});
			session.setAttribute(AuthServerConstant.LOGIN_USER, data);
			return "redirect:http://xxsc.com";
		} else {
			Map<String, String> errorMap = new HashMap<>();
			errorMap.put("msg", r.getData("msg", new TypeReference<String>() {
			}));
			redirectAttributes.addFlashAttribute("errors", errorMap);
			return "redirect:http://auth.xxsc.com/login.html";
		}

	}

}
